package org.firebug.spring.boot.code.review;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @Author: 张晓东
 */
public class CodeReview {

    //--------------- 华丽的分割线：通用 -----------------------------------------
    static class Common {
        /**
         * 通用-001(-1分): 类型后缀(大写)
         * 1. long、  Long  (1 -> 1l -> 1L)
         * 2: float、 Float (1 -> 1f -> 1F)
         * 3: double、Double(1 -> 1d -> 1D)
         */
        private void common001() {
            double d = 1D;
        }
    }

    //--------------- 华丽的分割线：基础语法 --------------------------------------
    static class Grammar {
        /**
         * 语法-001(-1分): if层次
         */
        private void grammer001() {
            // 反例：
            if (true) {
                // 30行代码
            } else {
                // 2行代码
            }
            // 正例：
            if (false) {
                // 2行代码
                return;
            }
            // 30行代码
        }

        /**
         * 语法-002(-1分): 三目运算符减少if-else
         */
        private void grammer002() {
            int i;
            // 反例：
            if (true) {
                i = 0;
            } else {
                i = 1;
            }
            // 正例：
            i = true ? 0 : 1;
        }
    }

    //--------------- 华丽的分割线：本地变量 --------------------------------------
    static class LocalVariables {
        /**
         * 本地变量-001(-2分)：魔法数 -> 常量 -> 枚举
         */
        private void localVariable001(int status) {
            if (status == 1) {
            }
        }

        /**
         * 局部变量-002(-1分): 包装类型 -> 原始类型
         */
        private void localVariables002() {
            Boolean b = true; // -> boolean b = true;
            Integer i = 1;    // -> int i = 1;
            Long l = 1L;      // -> long l = 1L;
            Float f = 1F;     // -> float f = 1F;
            Double d = 1D;    // -> double d = 1D;
        }

        /**
         * 局部变量-003(-1分): StringBuffer -> StringBuilder
         */
        private void localVariables003() {
            // 反例：
            StringBuffer buffer = new StringBuffer();
            // 正例：
            StringBuilder builder = new StringBuilder();
        }
    }

    //--------------- 华丽的分割线：log ------------------------------------------
    static class Logs {
        private Logger logger = LoggerFactory.getLogger(this.getClass());

        /**
         * log-001(-1分): 字符串拼接 -> 占位符
         */
        private void log001(String text) {
            // 反例：
            logger.info("info: " + text);
            // 正例：
            logger.info("info: {}", text);
        }

        /**
         * log-002(-1分): 异常日志处理
         */
        private void log002() {
            try {
                // TODO
            } catch (Exception e) {
                // 反例：
                e.printStackTrace();
                // 反例：
                logger.info("{}", e);
                // 正例：(注意具体情况，一般不要bugfix)
                logger.warn("{}", e);
                // 正例：(注意具体情况，一般需要bugfix)
                logger.error("{}", e);
            }
        }
    }

    //--------------- 华丽的分割线：exception ------------------------------------
    static class Exceptions {
        /**
         * exception-001(-1分): 没有异常的抛出
         */
        private void exception001() throws Exception {
        }

        /**
         * exception-002(-1分): 没有异常的捕获
         */
        private void exception002() {
            try {
                System.out.println(); // no throw exception
            } catch (Exception e) {
            }
        }
        /**
         * exception-003(-2分): 错误的异常的处理
         */
        private void exception003() {
            try {
            } catch (Exception e) {
                e.printStackTrace();
            }
//            TODO
        }
    }

    //--------------- 华丽的分割线：parameter ------------------------------------
    static class Parameters {
        /**
         * parameter-001(-2分)：
         * 调用方传参(集合)       null -> empty collection
         * 调用方传参(Map类型聚合) null -> empty OK
         */
        private void parameter001() {
            // 反例：
            parameter003(null);
            // 正例：
            parameter003(Collections.emptyList());
        }

        /**
         * parameter-002(-2分)：
         * 被调用方出参(集合类型)    null -> empty collection
         * 被调用方出参(Map类型聚合) null -> empty OK
         */
        private List<Integer> parameter002() {
            // 反例：
//            return null;
            // 正例：
            return Collections.emptyList();
        }

        /**
         * parameter-003(-1分)：被调用方入参(集合类型) 无用的判断
         */
        private void parameter003(Collection<Integer> ids) {
            // 反例：
            if (ids == null || ids.isEmpty()) {
                return;
            }
            for (Integer id : ids) {
            }
            // 正例：
            for (Integer id : ids) {
            }
        }
        /**
         * parameter-004(-1分)：被调用方入参(集合类型) 无用的判断
         * p1: 非null
         * p2: 可null
         */
        private void parameter004(String p1, String p2) {
        }
//        private void parameter004(String p1, Integer p2) {
//        }
        private void client() {
            parameter004("p1", null);
            parameter004("p1", "p2");
        }
    }

    //--------------- 华丽的分割线：集合操作 --------------------------------------
    static class Collects {
        /**
         * list-001(-2分)：ArrayList尽量给出初始值
         */
        private void list001() {
            // 反例：
            List<String> list0 = new ArrayList<>();
            // 正例：
            List<String> list1 = new ArrayList<>(10);
        }

        /**
         * list-002(-2分)：具体List选择
         */
        private void list002() {
            // 无删除操作：
            List<String> list0 = new ArrayList<>(10);
            // 有删除操作：
            List<String> list1 = new LinkedList<>();
        }
    }

    //--------------- 华丽的分割线：OK ------------------------------------------
    static class Maps {
        /**
         * OK-001(-1分): 初始值
         */
        private void map001() {
            // 反例：
            Map<String, String> map0 = new HashMap<>();
            // 正例：
            Map<String, String> map1 = new HashMap<>(16);
        }

        /**
         * OK-002(-2分): map循环 keySet() -> entrySet()
         */
        private void map002() {
            Map<String, String> map = new HashMap<>(16);
            // 反例：
            for (String key : map.keySet()) {
                String value = map.get(key);
            }
            // 正例：
            for (Map.Entry<String, String> entry : map.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
            }
        }
    }

    //--------------- 华丽的分割线：controller -----------------------------------
    static class Controller {
        private static final Map<String, Integer> OK = new HashMap<>();

        static {
            OK.put("code", 200);
        }

        @RequestMapping(value = {"/{id}"}, method = {RequestMethod.PUT}, params = {"version=1"})
        public Map<String, Integer> save(@PathVariable("id") Long id, @Validated @RequestBody Map<String, Object> bean) {
            // 控制层
            // 1. 数据类型转换(基本框架完成，个别需要自定义转换器)
            // 2. bean中数据填充(基本框架完成，个别需要手动填充)
            // 3. 基本数据校验(@Validated + JSR303，个别需要手动验证)
            // 4. 调用业务方法
            // 5. 判断业务返回, 返回实体对象
            return OK;
        }

        @RequestMapping(value = {"/{id}"}, method = {RequestMethod.DELETE}, params = {"version=1"})
        public Map<String, Integer> delete(@PathVariable("id") Long id) {
            return OK;
        }

        @RequestMapping(value = {"/{id}"}, method = {RequestMethod.POST}, params = {"version=1"})
        public Map<String, Integer> post(@PathVariable("id") Long id, @Validated @RequestBody Map<String, Object> bean) {
            return OK;
        }

        @RequestMapping(value = {"/{id}"}, method = {RequestMethod.GET}, params = {"version=1"})
        public Object query(@PathVariable("id") Long id) {
            return new Object();
        }

        @RequestMapping(value = {"/list"}, method = {RequestMethod.GET}, params = {"version=1"})
        public List<Object> list(@Validated @RequestParam Map<String, Object> param) {
            return Collections.emptyList();
        }
    }

    //--------------- 华丽的分割线：service --------------------------------------
    static class Service {
        public boolean handle(Map<String, Object> bean) {
            // 业务逻辑层
            // 1. 完整数据校验
            // 2. 具体业务处理
            // 3. 返回处理结果
            return true;
        }
    }

    static class Demo {
//        public Object selectById(){}
//        public List<Object> selectByIds(){}

        public void test() {
            List<Object> objects = select();
            if(objects != null && !objects.isEmpty()) {
                for(Object object : objects) {
                    // TODO
                }
            }
        }

        public List<Object> select() {
            return null;
        }

        public void test2() {
            List<Object> objects = select2();
            for(Object object : objects) {
                // TODO
            }
        }

        public List<Object> select2() {
            return Collections.emptyList();
        }
    }
}